﻿// Copyright (c) 2010
// by http://openlightgroup.net/

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel;

namespace SilverlightDebate
{
    // A type from which to derive the contract name that is used to export the
    // type or member marked with this attribute,
    public interface IDeploymentCatalogService
    {
        // The class that will implement this interface will implement these two methods
        void AddXap(string uri, Action<AsyncCompletedEventArgs> completedAction = null);
        void RemoveXap(string uri);
    }

    // See: Building Hello MEF – Part IV – DeploymentCatalog
    // http://codebetter.com/blogs/glenn.block/archive/2010/03/07/building-hello-mef-part-iv-deploymentcatalog.aspx
    // See: Silverlight 4, MEF and MVVM: MEFModules, Dynamic XAP Loading and Navigation Applications
    // http://blog.answermyquery.com/2010/04/silverlight-4-mef-and-mvvm-mefmodules-dynamic-xap-loading-and-navigation-applications/
    [Export(typeof(IDeploymentCatalogService))]
    public class DeploymentCatalogService : IDeploymentCatalogService
    {
        private static AggregateCatalog _aggregateCatalog;
        Dictionary<string, DeploymentCatalog> _catalogs;

        public DeploymentCatalogService()
        {
            _catalogs = new Dictionary<string, DeploymentCatalog>();
        }

        public static void Initialize()
        {
            _aggregateCatalog = new AggregateCatalog();
            _aggregateCatalog.Catalogs.Add(new DeploymentCatalog());
            CompositionHost.Initialize(_aggregateCatalog);
        }

        public void AddXap(string uri, Action<AsyncCompletedEventArgs> completedAction = null)
        {
            // Add a .xap to the catalog
            DeploymentCatalog catalog;
            if (!_catalogs.TryGetValue(uri, out catalog))
            {
                catalog = new DeploymentCatalog(uri);

                if (completedAction != null)
                {
                    catalog.DownloadCompleted += (s, e) => completedAction(e);
                }
                else
                {
                    catalog.DownloadCompleted += catalog_DownloadCompleted;
                }

                catalog.DownloadAsync();
                _catalogs[uri] = catalog;
                _aggregateCatalog.Catalogs.Add(catalog);
            }
        }

        void catalog_DownloadCompleted(object sender, AsyncCompletedEventArgs e)
        {
            // Chekcks for errors loading the .xap
            if (e.Error != null)
            {
                throw e.Error;
            }
        }

        public void RemoveXap(string uri)
        {
            // Remove a .xap from the catalog
            DeploymentCatalog catalog;
            if (_catalogs.TryGetValue(uri, out catalog))
            {
                _aggregateCatalog.Catalogs.Remove(catalog);
                _catalogs.Remove(uri);
            }
        }
    }
}
